package com.sf.dlb.service;
import com.sf.dlb.bean.ETHWalletRequestBean;
import com.sf.dlb.bean.WalletRquestBean;
import com.sf.dlb.config.Global;
import com.sf.dlb.constant.CacheConstant;
import com.sf.dlb.constant.ResponseConstant;
import com.sf.dlb.jpa.model.*;
import com.sf.dlb.jpa.repository.*;
import com.sf.dlb.mapper.dao.UserDlbRecodMapper;
import com.sf.dlb.mapper.dao.UserGradeMapper;
import com.sf.dlb.utils.*;
import com.sf.dlb.vo.*;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ExecutorService;


/**
 * Created by jing.tan on 2018/5/21.
 */
@Service
public class UserWalletService extends BaseUserWalletService{
    private static Logger logger = LoggerFactory.getLogger(UserWalletService.class);
    @Autowired
    private UserWalletRepository userWalletRepository;
    @Autowired
    private WalletLockRepository walletLockRepository;
    @Autowired
    private WalletExtractRepository walletExtractRepository;
    @Autowired
    private SmsInfoService smsInfoService;
    @Autowired
    private UserInfoRepository userInfoRepository;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private WalletAddressService WalletAddressService;
    @Autowired
    private UserDlbRecordService userDlbRecordService;
    @Autowired
    private UserRealInfoRepository userRealInfoRepository;
    @Autowired
    private ETHWalletService userETHWalletService;
    @Autowired
    private WalletEthAddressService walletEthAddressService;
    @Autowired
    private WalletTopupService walletTopupService;
    @Autowired
    private BackThreadService backThreadService;
    @Autowired
    private UserDlbRecodMapper userDlbRecodMapper;
    @Autowired
    private UserDlbRecordRepository userDlbRecordRepository;
    @Resource
    private ExecutorService executorService;
    @Resource
    private Global global;
    @Autowired
    private RedisUtil redisUtil;
    /**
     * 更新用户钱包-增加
     */
    @Transactional
    public UserWalletInfo updateUserWallet(String userId,Double getDlb,String source,String sourceDesc){
        logger.info("updateUserWallet userId={},getDlb={},source={},sourceDesc={},",userId,getDlb,source,sourceDesc);
        UserWalletInfo userWalletInfo= userWalletRepository.findByUserIdAndDelFlag(userId,"0");
        if(null==userWalletInfo){
            logger.info("updateUserWallet userWalletInfo is null");
            userWalletInfo=new UserWalletInfo();
            userWalletInfo.setCreateDate(new Date());
            userWalletInfo.setUserId(userId);
        }
        if(null!=getDlb){
            Double lockDlb=userWalletInfo.getLockDlb();
            lockDlb=(null==lockDlb?0.0:lockDlb);
            Double currentdlbCount=getDlb;
            userWalletInfo.setLockDlb(Arith.add(lockDlb,currentdlbCount));
            userWalletInfo.setUpdateDate(new Date());
            userWalletInfo= userWalletRepository.save(userWalletInfo);
            //更新用户dlb流水表
            userDlbRecordService.generateDlbRecord(userId+"",source,sourceDesc,currentdlbCount,ResponseConstant.type_add);
        }
        logger.info("updateUserWallet userWalletInfo={}",GsonUtils.getInstance().toJson(userWalletInfo));
        return userWalletInfo;
    }
    /**
     * 更新用户钱包-可用dlb减少
     */
    @Transactional
    public UserWalletInfo userWalletAvailableDlbSub(String userId, Double subDlb, String source, String sourceDesc){
        logger.info("userWalletAvailableDlbSub userId={},getDlb={},getType={},source={},sourceDesc={},",userId,subDlb,source,sourceDesc);
        UserWalletInfo userWalletInfo= userWalletRepository.findByUserIdAndDelFlag(userId,"0");
        if(null==userWalletInfo){
            logger.info("userWalletAvailableDlbSub userWalletInfo is null");
            return null;
        }
        //更新用户钱包-可用dlb
        Double availableDlb=userWalletInfo.getAvailableDlb();
        Double extractChargeCount=subDlb;
        availableDlb=(availableDlb==null?0.0:availableDlb);
        extractChargeCount=(extractChargeCount==null?0.0:extractChargeCount);
        userWalletInfo.setAvailableDlb(Arith.sub(availableDlb,extractChargeCount));
        userWalletInfo.setUpdateDate(new Date());
        userWalletInfo=userWalletRepository.save(userWalletInfo);
        logger.info("userWalletAvailableDlbSub availableDlb={} ",availableDlb,extractChargeCount);
        //更新流水表
        userDlbRecordService.generateDlbRecord(userId+"",source, sourceDesc,extractChargeCount,ResponseConstant.type_sub);
        return userWalletInfo;
    }
    /**
     * 用户钱包-锁定dlb减少
     */
    @Transactional
    public UserWalletInfo userWalletLockDlbSub(String userId,Double subDlb,String source,String sourceDesc){
        logger.info("userWalletLockDlbSub userId={},getDlb={},getType={},source={},sourceDesc={},",userId,subDlb,source,sourceDesc);
        UserWalletInfo userWalletInfo= userWalletRepository.findByUserIdAndDelFlag(userId,"0");
        if(null==userWalletInfo){
            logger.info("userWalletLockDlbSub userWalletInfo is null");
            return null;
        }
        //更新用户钱包-可用dlb
        Double lockDlb=userWalletInfo.getLockDlb();
        Double extractChargeCount=subDlb;
        extractChargeCount=(extractChargeCount==null?0.0:extractChargeCount);
        userWalletInfo.setLockDlb(Arith.sub(lockDlb,extractChargeCount));
        userWalletInfo.setUpdateDate(new Date());
        userWalletInfo=userWalletRepository.save(userWalletInfo);
        logger.info("userWalletLockDlbSub lockDlb={},extractChargeCount={}",lockDlb,extractChargeCount);
        //更新流水表
        userDlbRecordService.generateDlbRecord(userId,source,sourceDesc,extractChargeCount,ResponseConstant.type_sub);
        return userWalletInfo;
    }
    /**
     * 获取用户钱包
     * @param userId
     * @return
     */
    @Transactional
    public ResultVO getUserWallet(final String userId){
        logger.info("getUserWallet start userId={}",userId);
        //查询用户以太坊，是否有充值记录->单例子线程按顺序去执行查询
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                walletTopupService.queryTopupSaveLocal(userId);
            }
        });
        UserWalletInfo userWalletInfo=userWalletRepository.findByUserIdAndDelFlag(userId,"0");
        Double lockDlb=0.0;
        Double unlockDlb=0.0;
        Double availableDlb=0.0;
        Double dlbCount;
        Double availableExtractDlb=0.0;
        Double extractCharge= handlerExtractCharge();

        if(null==userWalletInfo){
            logger.info(" getUserWallet userWalletInfo is null ");
        }else{
            lockDlb=userWalletInfo.getLockDlb();
            availableDlb=userWalletInfo.getAvailableDlb();
            unlockDlb=userWalletInfo.getUnlockDlb();
            StringBuffer logSb=new StringBuffer();
            logSb.append("lockDlb=").append(lockDlb).append(" & availableDlb=").append(availableDlb).append(" & unlockDlb=").append(unlockDlb);
            logger.info(" getUserWallet userWalletInfo is "+logSb);
        }
        //null判断
        lockDlb=(null==lockDlb?0.0:lockDlb);
        availableDlb=(null==availableDlb?0.0:availableDlb);
        unlockDlb=(null==unlockDlb?0.0:unlockDlb);

        UserWalletVO userWalletVO=new UserWalletVO();
        userWalletVO.setLockDlb(StringFormatUtils.kill3Decimals(lockDlb));
        userWalletVO.setUnlockDlb(unlockDlb.intValue()+"");
        userWalletVO.setAvailableDlb(availableDlb.intValue()+"");
        dlbCount = Arith.add(Arith.add(lockDlb,unlockDlb),availableDlb);
        userWalletVO.setDlbCount(StringFormatUtils.kill3Decimals(dlbCount));
        userWalletVO.setExtractCharge(extractCharge.intValue()+"");
        userWalletVO.setAvailableExtractDlb(availableDlb.intValue()+""); //提现的数量包含了手续费，所以可用多少就可以提多少
        logger.info("==getUserWallet end userWalletVO={}",GsonUtils.getInstance().toJson(userWalletVO));
        //权益部分
        List<UserDlbRecordInfo> userDlbRecordInfos=userDlbRecordRepository.findByUserIdAndDelFlagOrderByCreateDateDesc(userId,"0");
        Double readEarnings=0.0;
        Double readDivideEarnings=0.0;
        Double invatationBuyDivideEarnings=0.0;
        Double videoEarnings=0.0;
        Double otherEarnings=0.0;
        for (UserDlbRecordInfo userDlbRecordInfo:userDlbRecordInfos) {
            String source=userDlbRecordInfo.getSource();
            String dlbType=userDlbRecordInfo.getDlbType();
            Double dlbNumber=userDlbRecordInfo.getDlbNumber();
            if(StringUtils.equals(source,ResponseConstant.source_type_reading)){
                readEarnings=Arith.add(readEarnings,dlbNumber);
            }else if(StringUtils.equals(source,ResponseConstant.source_type_read_divide)){
                readDivideEarnings=Arith.add(readDivideEarnings,dlbNumber);
            }else if(StringUtils.equals(source,ResponseConstant.source_type_buy_grade_divide)){
                invatationBuyDivideEarnings=Arith.add(invatationBuyDivideEarnings,dlbNumber);
            }else if(StringUtils.equals(source,ResponseConstant.source_type_video)){
                videoEarnings=Arith.add(videoEarnings,dlbNumber);
            }else if(StringUtils.equals(source,ResponseConstant.source_type_register)||StringUtils.equals(source,ResponseConstant.source_type_the_invitation)
                    ||StringUtils.equals(source,ResponseConstant.source_type_extract)||StringUtils.equals(source,ResponseConstant.source_type_topup)
                    ||StringUtils.equals(source,ResponseConstant.source_type_recycling)||StringUtils.equals(source,ResponseConstant.source_type_other)){
                //包含：注册，邀请，提现，充值，回收，其他
                //类型(1增加，2减少)
                if(StringUtils.equals(dlbType,"1")){
                    otherEarnings=Arith.add(otherEarnings,dlbNumber);
                }else{
                    otherEarnings=Arith.add(otherEarnings,-dlbNumber);
                }
            }else{
              continue;
            }
        }
        userWalletVO.setReadEarnings(StringFormatUtils.kill3Decimals(readEarnings));
        userWalletVO.setReadDivideEarnings(StringFormatUtils.kill3Decimals(readDivideEarnings));
        userWalletVO.setInvatationBuyDivideEarnings(StringFormatUtils.kill3Decimals(invatationBuyDivideEarnings));
        userWalletVO.setVideoEarnings(StringFormatUtils.kill3Decimals(videoEarnings));
        userWalletVO.setOtherEarnings(StringFormatUtils.kill3Decimals(otherEarnings));
        return ResultVOUtil.success(userWalletVO);
    }
    //提现手续费
    public Double handlerExtractCharge(){
        return global.wallet_extract_charge;
    }
    /**
     * 申请解锁dlb
     * @param walletRquestBean
     * @return
     */
    public ResultVO applyUnlockDlb(WalletRquestBean walletRquestBean){
        logger.info("==applyUnlockDlb start walletRquestBean={}",GsonUtils.getInstance().toJson(walletRquestBean));
        String userId=walletRquestBean.getUserId();
        //@TODO  防止高并发
        synchronized (userWalletRepository) {
            UserWalletInfo userWalletInfo = userWalletRepository.findByUserIdAndDelFlag(userId, "0");
            if (null == userWalletInfo) {
                logger.info(" applyUnlockDlb userWalletInfo is null ");
                return ResultVOUtil.error(ResponseConstant.ERROR, "暂无解锁数据");
            }
            Double correntLockDlb = userWalletInfo.getLockDlb();
            Integer currentUnlockCount = walletRquestBean.getUnlockCount();
            if (currentUnlockCount > correntLockDlb) {
                logger.info(" applyUnlockDlb unlockCount>correntLockDlb  ");
                return ResultVOUtil.error(ResponseConstant.ERROR, "解锁数量不能大于锁定数量");
            }
            //已锁定dlb-需要减少
            Double lockDlb = Arith.sub(correntLockDlb, currentUnlockCount);
            Double unlockDlb = userWalletInfo.getUnlockDlb();
            unlockDlb = (null == unlockDlb ? 0.0 : unlockDlb);
            unlockDlb = Arith.add(unlockDlb, currentUnlockCount);
            userWalletInfo.setLockDlb(lockDlb);
            userWalletInfo.setUnlockDlb(unlockDlb);
            userWalletInfo.setUpdateDate(new Date());
            userWalletRepository.save(userWalletInfo);
            logger.info("applyUnlockDlb userWalletInfo={}", GsonUtils.getInstance().toJson(userWalletInfo));
            //解锁dlb添加到解锁列表中
            WalletLockInfo walletLockInfo = new WalletLockInfo();
            walletLockInfo.setLockNumber(IdentifyCodeUtil.orderId() + "");
            walletLockInfo.setUserId(userId);
            walletLockInfo.setLockCount(currentUnlockCount.doubleValue());
            walletLockInfo.setLockState(ResponseConstant.unlock_state_for);
            walletLockInfo.setLockType(ResponseConstant.apply_unlock_dlb);
            walletLockInfo.setCreateDate(new Date());
            walletLockInfo.setUpdateDate(new Date());
            walletLockRepository.save(walletLockInfo);
            logger.info("applyUnlockDlb walletLockInfo={}",GsonUtils.getInstance().toJson(walletLockInfo));
        }
        return ResultVOUtil.success();
    }
    /**
     * 申请锁定dlb
     * @param walletRquestBean
     * @return
     */
    public ResultVO applylockDlb(WalletRquestBean walletRquestBean){
        logger.info("==applylockDlb start walletRquestBean={}",GsonUtils.getInstance().toJson(walletRquestBean));
        String userId=walletRquestBean.getUserId();
        UserWalletInfo userWalletInfo=userWalletRepository.findByUserIdAndDelFlag(userId,"0");
        if(null==userWalletInfo){
            logger.info(" applylockDlb userWalletInfo is null ");
            return ResultVOUtil.error(ResponseConstant.ERROR,"暂无锁定数据");
        }
        //@TODO  防止高并发
        synchronized (this) {
            Double correntAvailableDlb = userWalletInfo.getAvailableDlb();
            correntAvailableDlb = (null == correntAvailableDlb ? 0.0 : correntAvailableDlb);
            Integer currentUnlockCount = walletRquestBean.getUnlockCount();
            if (currentUnlockCount > correntAvailableDlb) {
                logger.info(" applylockDlb unlockCount>correntLockDlb  ");
                return ResultVOUtil.error(ResponseConstant.ERROR, "锁定数量不能大于可用数量");
            }
            //可用的dlb-需要减少
            Double availableDlb = Arith.sub(correntAvailableDlb, currentUnlockCount);
            //已锁定的dlb需要增加
            Double lockDlb = userWalletInfo.getLockDlb();
            lockDlb = (null == lockDlb ? 0.0 : lockDlb);
            lockDlb = Arith.add(lockDlb, currentUnlockCount);
            //更新钱包
            userWalletInfo.setLockDlb(lockDlb);
            userWalletInfo.setAvailableDlb(availableDlb);
            userWalletInfo.setUpdateDate(new Date());
            userWalletRepository.save(userWalletInfo);
            logger.info("applylockDlb userWalletInfo={}", GsonUtils.getInstance().toJson(userWalletInfo));
            //锁定dlb添加到锁列表中
            WalletLockInfo walletLockInfo = new WalletLockInfo();
            walletLockInfo.setLockNumber(IdentifyCodeUtil.orderId() + "");
            walletLockInfo.setUserId(userId);
            walletLockInfo.setLockCount(currentUnlockCount.doubleValue());
            walletLockInfo.setLockState(ResponseConstant.unlock_state_complete);
            walletLockInfo.setLockType(ResponseConstant.apply_lock_dlb);
            walletLockInfo.setCreateDate(new Date());
            walletLockInfo.setUpdateDate(new Date());
            walletLockRepository.save(walletLockInfo);
            logger.info("applylockDlb walletLockInfo={}", GsonUtils.getInstance().toJson(walletLockInfo));
        }
        return ResultVOUtil.success();
    }
    /**
     * 申请解锁列表-分页
     * @param walletRquestBean
     * @return
     */
    public ResultVO unlockDlbList(WalletRquestBean walletRquestBean){
        logger.info("==unlockDlbList start walletRquestBean={}",GsonUtils.getInstance().toJson(walletRquestBean));
        String userId=walletRquestBean.getUserId();
        String unlockListType=walletRquestBean.getUnlockListType();
        String lockType=walletRquestBean.getLockType();
        int pageSize=walletRquestBean.getPageSize();
        int currentPages=walletRquestBean.getCurrentPages();
        WalletLockInfo walletLockInfo=new WalletLockInfo();
        walletLockInfo.setDelFlag("0");
        walletLockInfo.setUserId(userId);
        if(StringUtils.isNotBlank(unlockListType)){
            walletLockInfo.setLockState(unlockListType);
        }
        if(StringUtils.isNotBlank(lockType)){
            walletLockInfo.setLockType(lockType);
        }
        Example<WalletLockInfo> example=Example.of(walletLockInfo);
        Sort sort=new Sort(Sort.Direction.DESC,"createDate");
        Pageable pageable=new PageRequest(currentPages,pageSize, sort);
        Page<WalletLockInfo> pageAll=walletLockRepository.findAll(example,pageable);
        //封装VO
        List<WalletLockInfo> walletLockInfoList=pageAll.getContent();
        List<WalletLockVO> walletLockVOS=new ArrayList<>();
        for (WalletLockInfo walletLockInfo1:walletLockInfoList) {
            WalletLockVO walletLockVO=new WalletLockVO();
            BeanUtils.copyProperties(walletLockInfo1,walletLockVO);
            walletLockVO.setLockStateValue(StateToValueUtils.switchLockStateValue(walletLockInfo1.getLockState()));
            walletLockVO.setLockTypeValue(StateToValueUtils.switchLockTypeValue(walletLockInfo1.getLockType()));
            walletLockVO.setLockTime(walletLockInfo1.getCreateDate().getTime());
            walletLockVOS.add(walletLockVO);
        }
        PageVO pageVO=new PageVO();
        pageVO.setDataList(walletLockVOS);
        pageVO.setPageSize(pageSize);
        pageVO.setCurrentPages(currentPages+1);//默认从0开始，返回前端要+1;
        pageVO.setFirstPage(pageAll.isFirst());
        pageVO.setLastPage(pageAll.isLast());
        pageVO.setTotalElements(pageAll.getTotalElements());
        pageVO.setTotalPages(pageAll.getTotalPages());
        return ResultVOUtil.success(pageVO);
    }
    /**
     * 取消解锁
     * @param walletRquestBean
     * @return
     */
    public ResultVO cancelLock(WalletRquestBean walletRquestBean){
        logger.info("==cancelLock start walletRquestBean={}",GsonUtils.getInstance().toJson(walletRquestBean));
        String userId=walletRquestBean.getUserId();
        String lockNumber=walletRquestBean.getLockNumber();
        WalletLockInfo walletLockInfo=walletLockRepository.findByLockNumberAndDelFlag(lockNumber,"0");
        if(null==walletLockInfo){
            logger.info("cancelLock walletLockInfo is null");
            return ResultVOUtil.error(ResponseConstant.ERROR,"数据不存在");
        }
        //判断用户操作的是否是自己的数据，防止用户A修改用户B的数据
        String tempUserId=walletLockInfo.getUserId();
        if(!tempUserId.equals(userId)){
            logger.info("cancelLock !tempUserId.equals(userId) tempUserId={},userId={}",tempUserId,userId);
            return ResultVOUtil.error(ResponseConstant.ERROR,"你没有权限修改此数据");
        }
        //解锁中的状态，才能被取消
        if(!walletLockInfo.getLockState().equals(ResponseConstant.unlock_state_for)){
            logger.info("cancelLock ！equest 3");
            return ResultVOUtil.error(ResponseConstant.ERROR,"数据不能被取消");
        }
        //更新状态为取消
        walletLockInfo.setLockState(ResponseConstant.unlock_state_cancel);
        walletLockInfo.setUpdateDate(new Date());
        walletLockRepository.save(walletLockInfo);
        //更新用户钱包-已锁定数量
        UserWalletInfo userWalletInfo=userWalletRepository.findByUserIdAndDelFlag(userId,"0");
        Double lockCount=walletLockInfo.getLockCount();
        Double userLockDlb=userWalletInfo.getLockDlb();
        Double userUnlockDlb=userWalletInfo.getUnlockDlb();
        userLockDlb=(null==userLockDlb?0.0:userLockDlb);
        userUnlockDlb=(null==userUnlockDlb?0.0:userUnlockDlb);
        userWalletInfo.setLockDlb(Arith.add(userLockDlb,lockCount)); //解锁数量需要增加
        userWalletInfo.setUnlockDlb(Arith.sub(userUnlockDlb,lockCount));//解锁中需要减少
        userWalletInfo.setUpdateDate(new Date());
        userWalletRepository.save(userWalletInfo);
        return ResultVOUtil.success();
    }
    /**
     * 提现dlb
     * @param walletRquestBean
     * @return
     */
    @Transactional
    public ResultVO extractDlb(WalletRquestBean walletRquestBean){
        logger.info("==extractDlb start walletRquestBean={}",GsonUtils.getInstance().toJson(walletRquestBean));
        String userId=walletRquestBean.getUserId();
        UserInfo userInfo=userInfoRepository.findByUserIdAndDelFlag(userId,"0");
        //校验是否已经实名认证
        UserRealInfo userRealInfo=userRealInfoRepository.findByUserIdAndDelFlag(userId,"0");
        if(null==userRealInfo){
            logger.info("extractDlb userRealInfo is null 用户未实名认证");
            return ResultVOUtil.error(ResponseConstant.ERROR,"用户未实名认证");
        }
        String tempRealState=userRealInfo.getState();
        if(!tempRealState.equals("3")){
            logger.info("extractDlb userRealInfo 实名认证正在审核中");
            return ResultVOUtil.error(ResponseConstant.ERROR,"实名认证正在审核中");
        }
        //验证提现地址是否合法
        String extractAddress=walletRquestBean.getExtractAddress();
        boolean addressValidation=userETHWalletService.chckoutExtractAddress(extractAddress);
        if(!addressValidation){
            logger.info("extractDlb addressValidation 提现地址不合法");
            return ResultVOUtil.error(ResponseConstant.ERROR,"提现地址不合法");
        }
        //校验验证码
        String validationCode=walletRquestBean.getValidationCode();
        ResultVO resultVO=smsInfoService.checkoutVerificationCode(userInfo.getMobile(),validationCode);
        if(resultVO.getCode()!=200){
            logger.info("extractDlb validationCode resultVO.getCode()!=200 ");
            return resultVO;
        }
        //校验支付密码
        String payPassword=walletRquestBean.getPayPassword();
        resultVO=userInfoService.checkoutPayPassword(userInfo.getPayPassword(),payPassword);
        if(resultVO.getCode()!=200){
            logger.info("extractDlb  payPassword resultVO.getCode()!=200 ");
            return resultVO;
        }
        //@TODO 使用redis防止高并发
        synchronized (userWalletRepository) {
            Integer extractCount = walletRquestBean.getExtractCount();//提现数量(包含了手续费)
            Double extractCharge = handlerExtractCharge();//手续费
            UserWalletInfo userWalletInfo = userWalletRepository.findByUserIdAndDelFlag(userId, "0");
            if (null == userWalletInfo) {
                logger.info("extractDlb userWalletInfo is null");
                return ResultVOUtil.error(ResponseConstant.ERROR, "暂无提取数据");
            }
            Double availableDlb = (userWalletInfo.getAvailableDlb() == null ? 0.0 : userWalletInfo.getAvailableDlb());
            if (extractCount > availableDlb) {
                logger.info("extractDlb extractCount>availableDlb ");
                return ResultVOUtil.error(ResponseConstant.ERROR, "提现数量不足");
            }
            //提现记录添加
            WalletExtractInfo walletExtractInfo = new WalletExtractInfo();
            long extractNumber = IdentifyCodeUtil.orderId();
            walletExtractInfo.setExtractNumber(extractNumber + "");
            walletExtractInfo.setUserId(userId);
            walletExtractInfo.setExtractAddress(extractAddress);
            walletExtractInfo.setExtractCount(extractCount.doubleValue());
            walletExtractInfo.setExtractCharge(extractCharge);
            walletExtractInfo.setExtractState(ResponseConstant.extract_state_audit);
            walletExtractInfo.setCreateDate(new Date());
            walletExtractInfo.setUpdateDate(new Date());
            walletExtractInfo = walletExtractRepository.save(walletExtractInfo);
            //公司账户
            WalletEthAddressInfo walletEthAddressInfo = walletEthAddressService.getCompanyETHAdress();//获取公司账户
            if (null == walletEthAddressInfo) {
                logger.info("extractDlb null==walletEthAddressInfo ");
                return ResultVOUtil.error(ResponseConstant.ERROR, "暂时无法提现");
            }
            //加入队列
            try {
                ETHWalletRequestBean ethWalletRequestBean = new ETHWalletRequestBean();
                ethWalletRequestBean.setUserId(walletExtractInfo.getUserId());
                ethWalletRequestBean.setSerialNumber(walletExtractInfo.getExtractNumber());
                ethWalletRequestBean.setToAddress(walletExtractInfo.getExtractAddress());
                //提现额度(包含了手续费)，应该减去手续费
                ethWalletRequestBean.setCount((int) (Arith.sub(extractCount, extractCharge)));
                ethWalletRequestBean.setFromAddress(walletEthAddressInfo.getAddress());
                ethWalletRequestBean.setPrivateKey(walletEthAddressInfo.getPrivateKey());
                backThreadService.queueConsumer.put(ethWalletRequestBean);
                backThreadService.queueConsumerList.add(ethWalletRequestBean);
            } catch (Exception e) {
                e.printStackTrace();
                logger.info("== extractDlb backThreadService.queueConsumer.put errer");
            }
            //更新用户钱包-可用dlb
            userWalletAvailableDlbSub(userId, extractCount.doubleValue(), ResponseConstant.source_type_extract, ResponseConstant.source_type_extract_value + ":extractNumber:" + walletExtractInfo.getExtractNumber());
            //地址列表更新-设置默认地址
            WalletAddressInfo walletAddressInfo = WalletAddressService.setDafaultAddress(userId, extractAddress);
            String extractAddressId = (null == walletAddressInfo ? "" : walletAddressInfo.getId().toString());
            walletExtractInfo.setExtractAddressId(extractAddressId);
            walletExtractInfo.setUpdateDate(new Date());
            walletExtractRepository.save(walletExtractInfo);
        }
        return ResultVOUtil.success();
    }
    /**
     * 提现列表-分页
     * @param walletRquestBean
     * @return
     */
    public ResultVO extractDlbList(WalletRquestBean walletRquestBean){
        int pageSize=walletRquestBean.getPageSize();
        int currentPages=walletRquestBean.getCurrentPages();
        String userId=walletRquestBean.getUserId();
        String extractListType=walletRquestBean.getExtractListType();

        WalletExtractInfo walletExtractInfo=new WalletExtractInfo();
        walletExtractInfo.setUserId(userId);
        walletExtractInfo.setDelFlag("0");
        if(StringUtils.isNotBlank(extractListType)){
            walletExtractInfo.setExtractState(extractListType);
        }
        Example<WalletExtractInfo> example=Example.of(walletExtractInfo);
        Sort sort=new Sort(Sort.Direction.DESC,"createDate");
        Pageable pageable=new PageRequest(currentPages,pageSize,sort);
        Page<WalletExtractInfo> pageAll=walletExtractRepository.findAll(example,pageable);
        List<WalletExtractInfo> extractInfoList=pageAll.getContent();
        //封装VO
        List<WalletExtractVO> walletExtractInfos=new ArrayList<>();
        for (WalletExtractInfo walletExtractInfo1:extractInfoList) {
            WalletExtractVO walletExtractVO=new WalletExtractVO();
            BeanUtils.copyProperties(walletExtractInfo1,walletExtractVO);
            walletExtractVO.setExtractCount(walletExtractVO.getExtractCount()); //提现数量需要去除手续费
            walletExtractVO.setExtractStateValue(StateToValueUtils.switchExtractStateValue(walletExtractInfo1.getExtractState()));
            walletExtractVO.setExtractTime(walletExtractInfo1.getCreateDate().getTime());
            walletExtractInfos.add(walletExtractVO);
        }
        PageVO pageVO=new PageVO();
        pageVO.setDataList(walletExtractInfos);
        pageVO.setPageSize(pageSize);
        pageVO.setCurrentPages(currentPages+1);//默认从0开始，返回前端要+1;
        pageVO.setFirstPage(pageAll.isFirst());
        pageVO.setLastPage(pageAll.isLast());
        pageVO.setTotalElements(pageAll.getTotalElements());
        pageVO.setTotalPages(pageAll.getTotalPages());
        return ResultVOUtil.success(pageVO);
    }
    /**
     * 获取dlb兑换价格
     */
    public void  getExchangePrice(double dlbCount,UserWalletVO userWalletVO){
        logger.info("getExchangePrice start ");
        String exchangePriceCacheKey=CacheConstant.USER_WALLET_PREFIX+CacheConstant.DLB_EXCHANGE_PRICE;
        Map hashMap=redisUtil.hmget(exchangePriceCacheKey);
        if(CollectionUtils.isEmpty(hashMap)){
            logger.info("getExchangePrice CollectionUtils.isEmpty(hashMap)");
            hashMap=userETHWalletService.queryCurrntExchangePrice();
            long keepTime=DateUtils.currentDistance24Long()/1000;//保留一天/秒
            redisUtil.hmset(exchangePriceCacheKey,hashMap,keepTime);
        }
        String priceETH= (String) hashMap.get("priceETH");
        String priceCNY= (String) hashMap.get("priceCNY");
        double ethExchangePrice=Arith.mul(dlbCount,Double.valueOf(priceETH));
        double cnyExchangePrice=Arith.mul(dlbCount,Double.valueOf(priceCNY));
        logger.info("getExchangePrice ethExchangePrice={},cnyExchangePrice={}",ethExchangePrice,cnyExchangePrice);
        userWalletVO.setEthExchangePrice(StringFormatUtils.killManyDecimals(ethExchangePrice,8));
        userWalletVO.setCnyExchangePrice(StringFormatUtils.killManyDecimals(cnyExchangePrice,8));
    }
}
